<?php

/**
 * Created by PhpStorm.
 * Script Name: Upgrade.php
 * Create: 2020/7/7 下午10:25
 * Description: 系统升级
 * Author: fudaoji<fdj@kuryun.cn>
 */
namespace app\admin\controller;


use ky\Logger;
use think\facade\Log;

class Upgrade extends Base
{
    private $uKey = 'kyphpToken';
    public $user = []; //开发者信息
    public $token = '';
    static public $baseUrl = 'https://kyphp.kuryun.com';
    static public $apis = [];
    private $client;

    public function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub
        set_time_limit(0); //防止超时
        self::$apis = [
            'getUser'       => 'user/getPost',
            'login'         => 'auth/loginPost',
            'download'      => 'app/downloadPost',
            'getVersions' => 'wxbot/getVersions',
            'getUpgradePackage' => 'wxbot/getUpgradePackage'
        ];
        $this->setClient();
        $this->getUserInfo();
        $this->assign('official_href', self::$baseUrl);
    }

    /**
     * 获取个人信息
     * @return array|mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function getUserInfo(){
        if (!empty($token = session($this->uKey))) {
            $this->token = $token;
            $res = $this->doRequest(['uri' => self::$apis['getUser']]);
            if($res['code'] == 1){
                $this->user = $res['data']['user'];
                if($this->user){
                    session($this->uKey, $token);
                }else{
                    session($this->uKey, null);
                }
            }
        }
        $this->assign['user'] = $this->user;
        $this->assign['token'] = $this->token;
        return $this->user;
    }

    /**
     * 设置请求客户端
     * Author: fudaoji<fdj@kuryun.cn>
     */
    private function setClient(){
        $this->client = new \GuzzleHttp\Client(['base_uri' => self::$baseUrl . '/api/']);
    }

    /**
     * 请求官方接口
     * @param array $params
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    protected function doRequest($params = []){
        $data = empty($params['data']) ? [] : $params['data'];
        $request = new \GuzzleHttp\Psr7\Request('post', $params['uri'], ['token' => $this->token]);
        try {
            $res = $this->client->send($request, [
                'json' => $data
            ]);
            if($res->getStatusCode() == 200){
                return json_decode($res->getBody()->getContents(), true);
            }else{
                echo "请求失败";exit;
            }
        }catch (\Exception $e){
            Log::error($e->getMessage());
            echo "请求异常";exit;
        }
    }

    /**
     * 版本列表
     * @return mixed
     */
    public function index(){
        if(request()->isPost()){
            $post_data = input('post.');
            $params = [
                'current_page' => $post_data['page'],
                'page_size' => $post_data['limit']
            ];
            $res = $this->doRequest(['uri' => self::$apis['getVersions'], 'data' => $params]);
            if($res['code'] != 1){
                $this->error($res['msg']);
            }
            $total = $res['data']['total'];
            $list = $res['data']['list'];
            $this->success('success', '', ['total' => $total, 'list' => $list]);
        }

        $builder = new ListBuilder();
        $builder->setTip("当前版本：<em class='layui-btn layui-badge layui-bg-blue'>".config('system.site.version')."</em>")
            //->addTopButton('self', ['title' => '升级到最新版本'])
            ->addTableColumn(['title' => '版本', 'field' => 'version'])
            ->addTableColumn(['title' => '版本描述', 'field' => 'desc'])
            ->addTableColumn(['title' => '发布时间', 'field' => 'create_time', 'type' => 'datetime', 'minWidth' => 170])
            ->addTableColumn(['title' => '操作', 'minWidth' => 120, 'type' => 'toolbar'])
            ->addRightButton('edit', ['lay-event' => 'ajax','title' => '升级到此版本','class' => 'layui-btn layui-btn-xs','data-ajax' => true,'data-confirm' => true, 'href' => url('upgradepost', ['id' => '__data_id__'])]);
        if(empty($this->user)){
            $builder->addTopButton('addnew', ['title' => '登录开发者社区', 'href' => url('login')]);
        }
        return $builder->show();
    }

    /**
     * 登录
     * @return mixed
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function login()
    {
        if($this->user){
            $this->redirect(url('index'));
        }
        if (request()->isPost()) {
            $data = input('post.');
            $params = [
                'username' => $data['username'],
                'password' => $data['password']
            ];
            $res = $this->doRequest(['uri' => self::$apis['login'], 'data' => $params]);
            if($res['code'] == 1){
                session($this->uKey, $res['data']['token']);
                $this->success($res['msg']);
            }else{
                $this->error($res['msg']);
            }
        }
        $builder = new FormBuilder();
        $builder->setMetaTitle('开发者登录')
            ->setPostUrl(url('login'))
            ->addFormItem('username', 'text', '账号', '在kyphp社区注册的手机账号', [], 'required')
            ->addFormItem('password', 'password', '密码', '密码', [], 'required')
            ->setBtnSubmit(['text' => '登录'])
            ->setBtnReset(['show' => 0]);

        return $builder->show();
    }

    /**
     * 升级应用
     * @throws \think\db\exception\BindParamException
     * @throws \think\exception\PDOException
     * @return mixed|\think\response\Json
     * Author: fudaoji<fdj@kuryun.cn>
     */
    public function upgradePost()
    {
        if (!$this->token)
            $this->error('请先登录开发者社区', url('login'));

        if (request()->isPost()) {
            $post_data = input('post.');
            $root_path = app()->getRootPath();
            $res = $this->doRequest(['uri' => self::$apis['getUpgradePackage'], 'data' => ['id' => $post_data['id']]]);
            if($res['code'] == 1){
                $upgrade = $res['data']['package'];
            }else{
                $this->error($res['msg']);
            }
            if($upgrade['version'] <= config('system.site.version')){
                $this->error('请选择大于系统当前版本的项进行升级！');
            }

            $zip = new \ZipArchive;
            $tem_file = env('runtime_path') . $upgrade['version'].'-'.time() . '.tmp';
            $package = http_post($upgrade['upgrade_url'], []);
            file_put_contents($tem_file, $package);

            try {
                $res = $zip->open($tem_file);
                if ($res === true) {
                    $zip->extractTo($root_path);
                    $zip->close();
                } else {
                    $this->error('解压失败，请检查是否有写入权限');
                }
            }catch (\Exception $e){
                $this->error('覆盖文件失败：' . $e->getMessage());
            }

            if (is_file($root_path . 'upgrade.sql')) {
                execute_sql($root_path . 'upgrade.sql');
                @unlink($root_path . 'upgrade.sql');
            }
            @unlink($tem_file);
            model('setting')->setDatas(['name' => 'site'], ['version' => $upgrade['version']]);
            $this->success('恭喜您，升级成功');
        }
    }
}